package cmds

import (
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/spf13/cobra"
	"github.com/xuri/excelize"

	"dev1.dfitc/futures/xls-update/daily"
)

var dailyCmd = &cobra.Command{
	Use:     "daily",
	Short:   "商品市场日累计",
	Long:    `商品市场日累计`,
	Example: `  xls-update daily`,
	Run: func(cmd *cobra.Command, args []string) {

	},
}

var dailyMatchCmd = &cobra.Command{
	Use:     "match",
	Short:   "成交额累计",
	Long:    `成交额累计`,
	Example: `  xls-update daily match`,
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			fmt.Println("[error] args#0 需要给出模板路径")
			return
		}
		if strings.EqualFold("", args[0]) {
			fmt.Println("[error] args#0 模板路径不能为空")
			return
		}

		// 检查日期参数
		// 如果用户没有输入日期，则设置为当前日期
		if strings.EqualFold("", TradeDate) {
			timestamp := time.Now().Unix()
			tm := time.Unix(timestamp, 0)
			TradeDate = tm.Format("20060102")
		}

		// 交易日期
		tTradeDate, err := time.Parse("20060102", TradeDate)
		if err != nil {
			fmt.Println("[error] " + err.Error())
			return
		}
		//strDate := tTradeDate.Format("2006/1/2")
		strDate := tTradeDate.Format("01-02-06")
		fmt.Println("[ info] 交易日期", strDate)

		// 打开输出文件
		xlsx, err := excelize.OpenFile(args[0])
		if err != nil {
			fmt.Println("[error] " + err.Error())
			return
		}
		fmt.Println("[ info] 打开模板文件成功")

		// 获取 sheet index
		sheetProduct := xlsx.GetSheetIndex("商品市场")
		productIndex := "sheet" + strconv.Itoa(sheetProduct)
		fmt.Println("[ info] 商品市场", productIndex)
		sheetMatch := xlsx.GetSheetIndex("成交额累计")
		matchIndex := "sheet" + strconv.Itoa(sheetMatch)
		fmt.Println("[ info] 成交额累计", matchIndex)
		sheetZhong := xlsx.GetSheetIndex("中金")
		zhongIndex := "sheet" + strconv.Itoa(sheetZhong)
		fmt.Println("[ info] 中金", zhongIndex)

		// 获取商成交额累计列数
		matchRows := xlsx.GetRows(matchIndex)
		matchCols := 0
		for _, v := range matchRows {
			if len(v) > matchCols {
				matchCols = len(v)
			}
		}
		fmt.Println("[ info] 成交额累计 列数", matchCols)

		// 初始为最后一行
		matchLastCol := matchCols
		matchWorkCol := matchLastCol + 1

		// 检查是否已经设置过
		// 默认只检查最近的60条历史
		start := matchCols - History
		end := matchCols
		if start <= 2 {
			start = 2 // 第1列是名称
		}
		fmt.Println("[ info] 成交额累计 start ", start)
		for i := start; i <= end; i++ {
			cell := daily.GetColName(i) + "1"
			fmt.Println("[ info] 成交额累计 单元格", cell)
			style, errstyle := xlsx.NewStyle(`{"number_format":14}`)
			if errstyle == nil {
				xlsx.SetCellStyle(matchIndex, cell, cell, style)
			}
			dateStr := xlsx.GetCellValue(matchIndex, cell)
			fmt.Println("[ info] 成交额累计 列日期", dateStr)
			if strings.EqualFold(strDate, dateStr) { // 与交易日期相同
				matchLastCol = i - 1
				matchWorkCol = matchLastCol + 1
				break
			} else if strings.EqualFold("", dateStr) { // 空行，一般是手工修改的行
				matchLastCol = i - 1
				matchWorkCol = matchLastCol + 1
				break
			}

			tDate, errt := time.Parse("01-02-06", dateStr)
			if errt != nil {
				fmt.Println(errt)
				matchLastCol = -1
				matchWorkCol = -1
				break
			}

			if i == 0 && tTradeDate.Before(tDate) {
				matchLastCol = -1
				matchWorkCol = -1
				break
			}
		}

		// 交易日期超出历史记录范围
		if -1 == matchLastCol && -1 == matchWorkCol {
			fmt.Println("[error] 交易日期超出检查范围")
			fmt.Println("[ info] 交易日期为：" + strDate)

			// 更新公式计算
			xlsx.UpdateLinkedValue()

			// 提示用户异常
			fmt.Println("[error] 异常退出")

			// 输出
			err := xlsx.Save()
			if err != nil {
				fmt.Println("[error]  " + err.Error())
				os.Exit(1)
			}
			return
		}

		fmt.Println("[ info] 处理的列号", daily.GetColName(matchWorkCol), matchWorkCol)

		daily.UpdateMatch(xlsx, matchIndex, productIndex, zhongIndex, tTradeDate, matchWorkCol, matchLastCol)

		// 更新公式计算
		xlsx.UpdateLinkedValue()

		fmt.Println("[ info] 修改完成")

		// 输出
		err = xlsx.Save()
		if err != nil {
			fmt.Println("[error] " + err.Error())
			os.Exit(1)
		}
	},
}

var dailyPosiCmd = &cobra.Command{
	Use:     "posi",
	Short:   "持仓额累计",
	Long:    `持仓额累计`,
	Example: `  xls-update daily posi`,
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			fmt.Println("[error] args#0 需要给出模板路径")
			return
		}
		if strings.EqualFold("", args[0]) {
			fmt.Println("[error] args#0 模板路径不能为空")
			return
		}

		// 检查日期参数
		// 如果用户没有输入日期，则设置为当前日期
		if strings.EqualFold("", TradeDate) {
			timestamp := time.Now().Unix()
			tm := time.Unix(timestamp, 0)
			TradeDate = tm.Format("20060102")
		}

		// 交易日期
		tTradeDate, err := time.Parse("20060102", TradeDate)
		if err != nil {
			fmt.Println("[error] " + err.Error())
			return
		}
		//strDate := tTradeDate.Format("2006/1/2")
		strDate := tTradeDate.Format("01-02-06")
		fmt.Println("[ info] 交易日期", strDate)

		// 打开输出文件
		xlsx, err := excelize.OpenFile(args[0])
		if err != nil {
			fmt.Println("[error] " + err.Error())
			return
		}
		fmt.Println("[ info] 打开模板文件成功 ", args[0])

		// 获取 sheet index
		sheetProduct := xlsx.GetSheetIndex("商品市场")
		productIndex := "sheet" + strconv.Itoa(sheetProduct)
		fmt.Println("[ info] 商品市场", productIndex)
		sheetPosi := xlsx.GetSheetIndex("持仓额累计")
		posiIndex := "sheet" + strconv.Itoa(sheetPosi)
		fmt.Println("[ info] 持仓额累计", posiIndex)
		sheetZhong := xlsx.GetSheetIndex("中金")
		zhongIndex := "sheet" + strconv.Itoa(sheetZhong)
		fmt.Println("[ info] 中金", zhongIndex)

		// 获取商成交额累计列数
		posiRows := xlsx.GetRows(posiIndex)
		posiCols := 0
		for _, v := range posiRows {
			if len(v) > posiCols {
				posiCols = len(v)
			}
		}
		fmt.Println("[ info] 持仓额累计 列数", posiCols)

		// 初始为最后一行
		posiLastCol := posiCols
		posiWorkCol := posiLastCol + 1

		// 检查是否已经设置过
		// 默认只检查最近的60条历史
		start := posiCols - History
		end := posiCols
		if start <= 2 {
			start = 2 // 第1列是名称
		}
		fmt.Println("[ info] 持仓额累计 start ", start)
		for i := start; i <= end; i++ {
			cell := daily.GetColName(i) + "1"
			fmt.Println("[ info] 持仓额累计 单元格", cell)
			style, errstyle := xlsx.NewStyle(`{"number_format":14}`)
			if errstyle == nil {
				xlsx.SetCellStyle(posiIndex, cell, cell, style)
			}
			dateStr := xlsx.GetCellValue(posiIndex, cell)
			fmt.Println("[ info] 持仓额累计 列日期", dateStr)
			if strings.EqualFold(strDate, dateStr) { // 与交易日期相同
				posiLastCol = i - 1
				posiWorkCol = posiLastCol + 1
				break
			} else if strings.EqualFold("", dateStr) { // 空行，一般是手工修改的行
				posiLastCol = i - 1
				posiWorkCol = posiLastCol + 1
				break
			}

			tDate, errt := time.Parse("01-02-06", dateStr)
			if errt != nil {
				fmt.Println(errt)
				posiLastCol = -1
				posiWorkCol = -1
				break
			}

			if i == 0 && tTradeDate.Before(tDate) {
				posiLastCol = -1
				posiWorkCol = -1
				break
			}
		}

		// 交易日期超出历史记录范围
		if -1 == posiLastCol && -1 == posiWorkCol {
			fmt.Println("[error] 交易日期超出检查范围")
			fmt.Println("[ info] 交易日期为：" + strDate)

			// 更新公式计算
			xlsx.UpdateLinkedValue()

			// 提示用户异常
			fmt.Println("[error] 异常退出")

			// 输出
			err := xlsx.Save()
			if err != nil {
				fmt.Println("[error] " + err.Error())
				os.Exit(1)
			}
			return
		}

		fmt.Println("[ info] 处理的列号", daily.GetColName(posiWorkCol), posiWorkCol)

		daily.UpdatePosi(xlsx, posiIndex, productIndex, zhongIndex, tTradeDate, posiWorkCol, posiLastCol)

		// 更新公式计算
		xlsx.UpdateLinkedValue()

		fmt.Println("[ info] 修改完成")

		// 输出
		err = xlsx.Save()
		if err != nil {
			fmt.Println("[error] " + err.Error())
			os.Exit(1)
		}
	},
}

func init() {
	dailyMatchCmd.Flags().IntVarP(&History, "history", "", 60, "检查时，参考的最后多少条记录, 默认最近60条记录")
	dailyPosiCmd.Flags().IntVarP(&History, "history", "", 60, "检查时，参考的最后多少条记录, 默认最近60条记录")
	dailyCmd.AddCommand(dailyMatchCmd)
	dailyCmd.AddCommand(dailyPosiCmd)
	rootCmd.AddCommand(dailyCmd)
}
